home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / tex / src / specialhost / specialhost.c < prev    next >
C/C++ Source or Header  |  1991-07-30  |  22KB  |  818 lines

  1. /* specialhost.c */
  2.  
  3.   /**************************************************************/
  4.   /*                                */
  5.   /* Bitte alle Aenderungen im Programm deutlich        */
  6.   /* markieren und mir zusenden. Ich werde dann         */
  7.   /* versuchen immer eine einheitliche Version          */
  8.   /* zusammenzubasteln.                     */
  9.   /*    30.07.90        (c) Georg Hessmann        */
  10.   /*                                */
  11.   /* Bug's und Anregungen bitte an:                */
  12.   /*             hessmann@unipas.fmi.uni-passau.de      */
  13.   /* oder an:                            */
  14.   /*                Georg Hessmann          */
  15.   /*                Oberer Markt 7          */
  16.   /*                8712 Volkach            */
  17.   /*                Germany             */
  18.   /*                                */
  19.   /*                                */
  20.   /* Program zur Auswertung der special Strings von TeX     */
  21.   /* wird von "ShowDVI" und "DVIprint" verwendet.        */
  22.   /* Das Programm muss im Hintergrund laufen noch bevor     */
  23.   /* die anderen Programme gestartet werden.            */
  24.   /* Die ist nur ein Beispiel, das die Arbeitsweise        */
  25.   /* dokumentieren soll.                    */
  26.   /*                                */
  27.   /* Das bisherige Format des special Kommandos:        */
  28.   /*    \special{ifffile=name                    */
  29.   /*         hoffset=fxx                    */
  30.   /*         voffset=fxx                    */
  31.   /*         hsize=fxx                    */
  32.   /*         vsize=fxx }                    */
  33.   /* wobei f eine real-Zahl ist und xx eine Einheit wie     */
  34.   /* in den anderen Programmen definiert.            */
  35.   /*                                */
  36.   /* Das Programm benoetigt die "iff.library"!          */
  37.   /*                                */
  38.   /* Version:                            */
  39.   /*                                */
  40.   /* -- 0.70    30.07.90    (hes) Georg Hessmann        */
  41.   /* -- 0.71    16.11.90    Verbesserungen von 'flextr.c'    */
  42.   /*                (MiL) Michael Illgner         */
  43.   /* -- 0.80    23.01.91    Verarbeitung von Farben!    */
  44.   /*                (MiL) Michael Illgner        */
  45.   /* -- 0.81    04.04.91    Neue Skalierungsroutinen,       */
  46.   /*                `flextr.c' jetzt überflüssig    */
  47.   /*                Olaf `Olsen' Barthel        */
  48.   /* -- 0.86    17.04.91        `flextr.c' wieder drin :)    */
  49.   /*                (hes)                */
  50.   /* -- 0.90    30.05.91        Einbau von Pull-Down Menues    */
  51.   /*                Einbau eines Config-Files    */
  52.   /*                Auswahl Blitter on/off        */
  53.   /*                Groessenbegrenzung bei Blitter    */
  54.   /*                Invert-Routine            */
  55.   /*                (hes)                */
  56.   /* -- 0.91    05.07.91    Zwei 'enforcer' hits behoben.    */
  57.   /*                GADGIMAGE-Gadgets eingefuehrt.    */
  58.   /*                PubScreen Support eingefuehrt.    */
  59.   /*                (hes)                */
  60.   /* -- 0.92    10.07.91    Kleine Probleme im Zusammenspiel*/
  61.   /*                Gadgets-Menues behoben.        */
  62.   /*                (hes)                */
  63.   /* -- 0.93    11.07.91    Probleme im TPIC Teil behoben.    */
  64.   /*                Dazu werden nun float Zahlen als*/
  65.   /*                Strings uebergeben, damit es    */
  66.   /*                keine Probleme FFP - IEEE gibt.    */
  67.   /*                Enforcer Hit in pline beseitigt.*/
  68.   /*                CTRL-E veranlasst SpecialHost    */    
  69.   /*                dazu, vom PubScr zu verschwinden*/
  70.   /*                (hes)                */
  71.   /* -- 0.94    30.07.91    Kleiner Bug in work_w_message    */
  72.   /*                behoben.            */
  73.   /*                (hes)                */
  74.   /*                                */
  75.   /**************************************************************/
  76.  
  77. static char ver[] = "$VER: SpecialHost "VERSION"  Copyright © 1990/91 Georg Heßmann. All Right Reserved. (last compiled: "__DATE__", "__TIME__")";
  78.  
  79.  
  80. #define DOSNAMESIZE    150
  81.  
  82. #ifndef ZERO
  83. #  define ZERO      0L
  84. #endif
  85.  
  86. #ifdef LATTICE
  87. long    _stack      = 5120;
  88. char *  _procname    = "SpecialHost";
  89. long    _priority    = 0;
  90. long    _BackGroundIO    = 1;
  91. extern  BPTR    _Backstdout;
  92. #endif
  93.  
  94. /* global variable */
  95. static struct special_map spmap;
  96. static char        bitfilename[DOSNAMESIZE];
  97.  
  98.  
  99. struct MsgPort      *special_port    = NULL;
  100. IFFFILE         ifffile     = NULL;
  101. struct BitMap        *bmap        = NULL;
  102. short            use_blitter    = TRUE;
  103. short            invert_bmap    = FALSE;
  104. short            is_os2        = FALSE;
  105. short            ECS_chips    = FALSE;
  106.  
  107. UBYTE            IFFColors[64];
  108. UBYTE            HAMColors[16][16][16];
  109. WORD            ColorTab[64];
  110.  
  111. extern struct Library        *IFFBase;        /* defined in specialwin.c */
  112. extern struct GfxBase        *GfxBase;
  113. extern struct IntuitionBase    *IntuitionBase;
  114.  
  115.  
  116.  
  117. static char    *TPICstr[] = {
  118.     "no command",
  119.     "PN", "PA", "FP", "IP", "DA", "DT", "SP", "SP", 
  120.     "AR", "IA", "SH", "SH", "SW", "BK", "TX", "overflow"
  121.   };
  122.  
  123.  
  124.  
  125. /* local funktions */
  126. static        void    free_bmap        (struct BitMap **bmap);
  127. static          int    MyCompareDates        (struct DateStamp *date1,
  128.                          struct DateStamp *date2);
  129. static        int    test_date        (char *iffile, char *bitfile, long *ssum);
  130. static        void    write_bmap        (char *name,
  131.                          struct BitMap *bmap,
  132.                          long ssum,
  133.                          long width, long height);
  134. static        int    get_iff_size        (char *name,
  135.                          long *width,
  136.                          long *height);
  137. static struct BitMap   *load_iff_picture    (struct parse_result *res,
  138.                          long *width,
  139.                          long *height,
  140.                          short to_chip);
  141. static struct BitMap   *work_with_message    (struct special_msg *message,
  142.                          int draw_modus, int base_dpi);
  143. static        int    scale_bmap        (struct special_map *map,
  144.                          struct BitMap **old_bmap,
  145.                          struct parse_result *res,
  146.                          int base_dpi,
  147.                          short to_chip);
  148.  
  149.  
  150.  
  151.  
  152. void close_port_bitm(void)
  153. {
  154.   if (special_port != NULL) {
  155.     DeletePort(special_port);
  156.   }
  157.   free_bmap(&bmap);
  158. }
  159.  
  160. static void free_bmap(struct BitMap **bmap)
  161. {
  162.  int i;
  163.  struct BitMap *map = (*bmap);
  164.  
  165.  if (map != NULL)
  166.  {
  167.   for (i=0; i<map->Depth; i++)
  168.   {
  169.    if (map->Planes[i] != NULL)
  170.    {
  171.     FreeMem(map->Planes[i],map->BytesPerRow*map->Rows);
  172.     map->Planes[i] = NULL;
  173.    }
  174.   }
  175.   free(map);
  176.   *bmap = NULL;
  177.  }
  178. }
  179.  
  180.  
  181. static int MyCompareDates(struct DateStamp *date1, struct DateStamp *date2)
  182. {
  183.   int ret = 1;
  184.  
  185.   if (memcmp(date1,date2,sizeof(struct DateStamp)) == 0) {
  186.     ret = 0;
  187.   }
  188.   else {
  189.     if (date1->ds_Days > date2->ds_Days) {
  190.       ret = -1;
  191.     }
  192.     else {
  193.       if (date1->ds_Days == date2->ds_Days) {
  194.         if (date1->ds_Minute > date2->ds_Minute) {
  195.       ret = -1;
  196.         }
  197.         else {
  198.       if (date1->ds_Minute == date2->ds_Minute && date1->ds_Tick > date2->ds_Tick) {
  199.         ret = -1;
  200.       }
  201.     }
  202.       }
  203.     }
  204.   }
  205.   return ret;
  206. }
  207.  
  208.  
  209.  
  210. static int test_date(char *iffile, char *bitfile, long *ssum)
  211. {
  212.   struct FileLock *lock_iff, *lock_bit;
  213.   struct FileInfoBlock *fib_iff, *fib_bit;
  214.   int ret = FALSE;
  215.   FILE *file;
  216.   long buffer;
  217.  
  218.   fib_iff  = (struct FileInfoBlock *)malloc((unsigned)sizeof(struct FileInfoBlock));
  219.   fib_bit  = (struct FileInfoBlock *)malloc((unsigned)sizeof(struct FileInfoBlock));
  220.   lock_iff = (struct FileLock *)Lock(iffile, ACCESS_READ);
  221.   lock_bit = (struct FileLock *)Lock(bitfile, ACCESS_READ);
  222.  
  223.   if (fib_iff != NULL && fib_iff != NULL && lock_iff != NULL && lock_bit != NULL) {
  224.     if (Examine((BPTR)lock_iff,fib_iff)!=0 && Examine((BPTR)lock_iff,fib_iff)!=0) {
  225.       ret = (MyCompareDates(&(fib_bit->fib_Date), &(fib_iff->fib_Date)) > 0);
  226.     }
  227.   }
  228.  
  229.   if (lock_iff) UnLock((BPTR)lock_iff);
  230.   if (lock_bit) UnLock((BPTR)lock_bit);
  231.   if (fib_iff) free(fib_iff);
  232.   if (fib_bit) free(fib_bit);
  233.  
  234.   if (ret) {
  235.     if ((file = fopen(bitfile,"r")) != NULL) {
  236.       if (fread((char *)&buffer,4,1,file) == 1) {
  237.     if (buffer != MAGIC_WORD) {
  238.       ret = FALSE;
  239.       pline("  wrong magic word in file %s!",bitfile);
  240.     }
  241.     else {
  242.       if (fread((char *)&buffer,4,1,file) != 1) {
  243.         ret = FALSE;
  244.       }
  245.       else {
  246.         *ssum = buffer;
  247.       }
  248.     }
  249.       }
  250.       fclose(file);
  251.     }
  252.   }
  253.  
  254.   return ret;
  255. }
  256.  
  257.  
  258. static void write_bmap(char *name, struct BitMap *bmap, long ssum, long width, long height)
  259. {
  260.   FILE *bmap_file;
  261.   long buffer;
  262.   int i;
  263.  
  264.   /* File Format: 4Bytes - magic word "SPEC"            */
  265.   /*          4Bytes - sum of \special-string        */
  266.   /*          4Bytes - length of rows in bits        */
  267.   /*          4Bytes - number of rows            */
  268.   /*          rows                      */
  269.   /*            length of one row is word (16Bit) aligned!! */
  270.  
  271.   if ((bmap_file = fopen(name,"w")) == NULL) {
  272.     pline("Can't write to bitmap-file (%s)!",name);
  273.     return;
  274.   }
  275.   buffer = (long)MAGIC_WORD;
  276.   fwrite((char *)&buffer,4,1,bmap_file);
  277.   buffer = ssum;
  278.   fwrite((char *)&buffer,4,1,bmap_file);
  279.   buffer = width;
  280.   fwrite((char *)&buffer,4,1,bmap_file);
  281.   buffer = height;
  282.   fwrite((char *)&buffer,4,1,bmap_file);
  283.   for (i=0; i<bmap->Rows; i++) {
  284.     fwrite(bmap->Planes[0]+(i*bmap->BytesPerRow),1,bmap->BytesPerRow,bmap_file);
  285.   }
  286.   fclose(bmap_file);
  287. }
  288.  
  289. static int get_iff_size(char *name, long *width, long *height)
  290. {
  291.   struct BitMapHeader *bmhd;
  292.  
  293.   if (IFFBase == NULL) {
  294.     if(!(IFFBase = OpenLibrary(IFFNAME,IFFVERSION))) {
  295.     pline("Copy the iff.library (Ver: %ld) to your LIBS: directory!",IFFVERSION);
  296.     return FALSE;
  297.     }
  298.   }
  299.  
  300.   if(!(ifffile=OpenIFF(name))) {
  301.     pline("Error opening iff-file \"%s\"!",name);
  302.     return FALSE;
  303.   }
  304.  
  305.   if(!(bmhd=GetBMHD(ifffile))) {
  306.     pline("BitMapHeader not found in iff-file \"%s\"",name);
  307.     return FALSE;
  308.   }
  309.   *width = bmhd->w;
  310.   *height = bmhd->h;
  311.  
  312.   CloseIFF(ifffile);
  313.   ifffile = NULL;
  314.  
  315.   return TRUE;
  316. }
  317.  
  318. /* new by MiL */
  319. /* calculate the gray values  with gamma-correction */
  320. static void make_colors(int numcolors, struct parse_result *res)
  321. {
  322.  float r, g, b, gam;
  323.  float fak;
  324.  int   i, ri, gi, bi;
  325.  
  326.  r = res->red; g = res->green; b = res->blue; gam = res->gamma;
  327.  fak = 255.0*pow(15.0*(r+g+b), -gam);
  328.  
  329.  for(i=0; i<numcolors; i++)
  330.   IFFColors[i] = (UBYTE)(fak*pow(((ColorTab[i] >> 8) & 0x0f)*r +
  331.                                ((ColorTab[i] >> 4) & 0x0f)*g +
  332.                         ((ColorTab[i] >> 0) & 0x0f)*b, gam));
  333.  if (res->mode == Ham)
  334.   for(ri=0; ri<16; ri++)for(gi=0; gi<16; gi++)for(bi=0; bi<16; bi++)
  335.    HAMColors[ri][gi][bi] = (UBYTE)(fak*pow(ri*r+gi*g+bi*b, gam));
  336. }
  337.  
  338. static struct BitMap *load_iff_picture (struct parse_result *res, long *width, long *height, short to_chip)
  339. {
  340.   struct BitMapHeader *bmhd;
  341.   struct BitMap *bmap;
  342.   int i, numcolors;
  343.  
  344.   if ((bmap = malloc(sizeof(struct BitMap))) == NULL) {
  345.     pline("Not enough memory for bitmap-structure!!!");
  346.     return NULL;
  347.   }
  348.   for (i=0; i<8; i++) {     /* importand */
  349.     bmap->Planes[i] = NULL;
  350.   }
  351.  
  352.   if (IFFBase == NULL) {
  353.     if(!(IFFBase = OpenLibrary(IFFNAME,IFFVERSION))) {
  354.     pline("Copy the iff.library (Ver: %ld) to your LIBS: directory!",IFFVERSION);
  355.     free(bmap);
  356.     return NULL;
  357.     }
  358.   }
  359.  
  360.   if(!(ifffile=OpenIFF(res->iffile))) {
  361.     pline("Error opening iff-file \"%s\"!",res->iffile);
  362.     free(bmap);
  363.     return NULL;
  364.   }
  365.  
  366.   if(!(bmhd=GetBMHD(ifffile))) {
  367.     pline("BitMapHeader not found in iff-file \"%s\"",res->iffile);
  368.     free(bmap);
  369.     return NULL;
  370.   }
  371.  
  372.     /* Olsen:    Statt manueller Initialisierung besser
  373.      *        durch die Systemroutine initialisieren
  374.      *        lassen (BltBitMap bekommt sonst Probleme).
  375.      */
  376.  
  377.   InitBitMap(bmap,bmhd->nPlanes,bmhd->w,bmhd->h);
  378.  
  379.   *width = bmhd->w;    /* in pixel */
  380.   *height = bmhd->h;    /* in pixel */
  381.  
  382.   for (i=0; i<bmap->Depth; i++) {
  383.     if (to_chip) {
  384.       bmap->Planes[i] = AllocMem(bmap->BytesPerRow*bmap->Rows,MEMF_CHIP|MEMF_CLEAR);
  385.     }
  386.     else {
  387.       bmap->Planes[i] = AllocMem(bmap->BytesPerRow*bmap->Rows,MEMF_PUBLIC|MEMF_CLEAR);
  388.     }
  389.     if (bmap->Planes[i] == NULL) {
  390.       free_bmap(&bmap);    /* gibt alles schon allozierte frei */
  391.       pline("NOT ENOUGH MEMORY!!! (%s-mem)", (to_chip) ? "chip" : "fast");
  392.       return NULL;
  393.     }
  394.   }
  395.  
  396.   if (bmap->Depth > 1 && res->mode == BandW) {
  397.     pline("Warning: This mode can't work with more than 2 colors!");
  398.   }
  399.  
  400.   /* bitmaps der Tiefe '1' brauchen keine color-map */
  401.   if (bmap->Depth > 1 && !(numcolors = GetColorTab(ifffile, ColorTab))) {
  402.     pline("picture has no colour table");
  403.     free_bmap(&bmap);
  404.     return NULL;
  405.   }
  406.  
  407.   if (numcolors > 0) {
  408.     make_colors(numcolors, res);
  409.   }
  410.  
  411.   if(!DecodePic(ifffile,bmap)) {
  412.     pline("Can't decode picture \"%s\"!",res->iffile);
  413.     free_bmap(&bmap);
  414.     return NULL;
  415.   }
  416.  
  417.   if (invert_bmap) {
  418.     int inv_i, inv_size;
  419.     ULONG * inv_ptr;
  420.  
  421.     /*
  422.      * I'm using longs here because it's more efficient on 32-bit-machines
  423.      * (A2500, A3000, A3001 Turbo Board etc.)
  424.      * The allocated memory chunk IS a multiple of 4 bytes!
  425.      *
  426.      */
  427.  
  428.     inv_size = (bmap->BytesPerRow*bmap->Rows)/4; /* size in long */
  429.  
  430.     for(inv_i=0,inv_ptr = (ULONG *)bmap->Planes[0]; inv_i<inv_size; inv_i++) {
  431.         *(inv_ptr++) ^= 0xFFFFFFFF;
  432.     }
  433.   }
  434.  
  435.   return bmap;
  436. }
  437.  
  438.  
  439. /* main function: verarbeitet die message und generiert eine Bitmap */
  440.  
  441. static struct BitMap *work_with_message(struct special_msg *message,
  442.                     int draw_modus, int base_dpi)
  443. {
  444.   struct parse_result res;
  445.   struct BitMap *bitmap = NULL;
  446.   char full_name[DOSNAMESIZE];
  447.   long width, height, ssum, ssum2;
  448.   char *str;
  449.   short to_chip;    /* Blitter oder nicht */
  450.  
  451.   to_chip = use_blitter;
  452.  
  453.  
  454.   pline("** received special string:   (hres: %d, vres: %d)",
  455.             message->hresolution,message->vresolution);
  456.   pline("   \"%s\"",message->special_string);
  457.  
  458.   res.iffile[0] = '\0';
  459.   res.hsize   = 0.0;
  460.   res.vsize   = 0.0;
  461.   res.hoffset = 0.0;
  462.   res.voffset = 0.0;
  463.   res.scale   = 0.0;
  464.   res.hscale  = 0.0;
  465.   res.vscale  = 0.0;
  466.   res.hres    = message->hresolution;
  467.   res.vres    = message->vresolution;
  468.   res.mode    = BandW;        /* BandW, Gray, Color or Ham */
  469.   res.red     = 1.0;
  470.   res.green   = 1.0;
  471.   res.blue    = 1.0;
  472.   res.gamma   = 0.5;
  473.  
  474.   ssum = ssum2 = 0;
  475.   for (str = message->special_string; str != NULL && *str != '\0'; ssum += (long)*str, str++);
  476.  
  477.   ParseSpecial(message->special_string, &res);
  478.   
  479.   if (res.mode != BandW && !(draw_modus == DRAW_BORDER || draw_modus == DRAW_RECT)) {
  480.     pline("  (Red,Green,Blue) = (%1.2f,%1.2f,%1.2f) Gamma = %1.2f",
  481.     res.red, res.green, res.blue, res.gamma);
  482.   }
  483.  
  484.  
  485.   spmap.hoffset = (long)(((float)message->hresolution * res.hoffset)+0.5);
  486.   spmap.voffset = (long)(((float)message->vresolution * res.voffset)+0.5);
  487.  
  488.   message->ret  = 0;
  489.   message->bmap = &spmap;
  490.   spmap.loc.map  = NULL;
  491.   spmap.where_is = LOC_NONE;
  492.  
  493.   if (res.iffile[0] != '\0') {
  494.     if (draw_modus == DRAW_BORDER || draw_modus == DRAW_RECT) {
  495.       if (get_iff_size(res.iffile,&width,&height)) {
  496.     spmap.width = width;            /* in pixel */
  497.     spmap.height = height;
  498.     if (draw_modus == DRAW_BORDER) {
  499.       spmap.where_is = LOC_BORDER;
  500.     }
  501.     else {
  502.       spmap.where_is = LOC_RECTANGLE;
  503.     }
  504.     (void) scale_bmap(&spmap, &bitmap, &res, base_dpi, 0);
  505.       }
  506.       else {
  507.     pline("iff-file ERROR! (transferred no picture)");
  508.     message->ret = 5;        /* not used */
  509.       }
  510.     }
  511.     else {
  512.       sprintf(full_name,"%s.%ldx%ld", res.iffile, res.hres, res.vres);
  513.       if ((draw_modus == DRAW_FILE || draw_modus == DRAW_FILE_B)
  514.       && test_date(res.iffile,full_name,&ssum2) && ssum == ssum2) {
  515.         /* full_name juenger als iffile und special unveraendert */
  516.     if (draw_modus == DRAW_FILE) {
  517.       spmap.where_is = LOC_FILE;
  518.     }
  519.     else {
  520.       spmap.where_is = LOC_FILE_BORDER;
  521.     }
  522.     strcpy(bitfilename,full_name);
  523.     spmap.loc.filename = bitfilename;
  524.       }
  525.       else {                /* iffile juenger als full_name */
  526.  
  527.     /* Wie wird ausgewaehlt, welche Routine zum Scalieren    */
  528.     /*  verwendet wird:                    */
  529.         /* erster Versuch: Laden des Bildes in's Chip-Mem    */
  530.         /*  wenn das fehlschlaegt wird nur noch mit Fast-Mem    */
  531.     /*  und der `flextr.c' Routine gearbeitet.        */
  532.     /* zweiter Versuch: Wenn das Bild ins Chip-Mem geladen    */
  533.     /*  ist, wird versucht es im Chip-Mem zu scalieren.    */
  534.     /* schlaegt das ebenfalls fehl, wird doch wieder auf    */
  535.     /* `flextr.c' zurueckgegriffen.                */
  536.     /* einen NACHTEIL hat das Verfahren allerdings:        */
  537.     /*  falls die Ausgangsbitmap in das Chip-Mem passt,    */
  538.     /*  die Zielbitmap aber ins Fast-Mem gelegt werden    */
  539.     /*  muss, wird beim scalieren staendig auf Chip-Mem    */
  540.     /*  zugegriffen! Pech fuer A3000 Besitzer!!        */
  541.     /*  (man sollte in dem Fall die Ausgangsbitmap wieder    */
  542.     /*  freigeben.)                        */
  543.     /* FEHLER!!                        */
  544.     /*  Hoehe/Breite groesser 1024 Pixel koennen nicht vom    */
  545.     /*  (alten ?) Blitter verarbeitet werden!!        */
  546.  
  547.     bitmap = load_iff_picture(&res,&width,&height, to_chip);  /* chip-mem */
  548.     if (bitmap == NULL) {
  549.       if (ifffile != NULL) {
  550.         CloseIFF(ifffile);
  551.         ifffile = NULL;
  552.       }
  553.       bitmap = load_iff_picture(&res,&width,&height, 0);      /* fast-mem */
  554.       to_chip = 0;
  555.     }
  556.  
  557.     if (bitmap != NULL) {
  558.       if (draw_modus == DRAW_IN_MEM_B || draw_modus == DRAW_FILE_B) {
  559.         spmap.where_is = LOC_BITMAP_BORDER;
  560.       }
  561.       else {
  562.         spmap.where_is = LOC_BITMAP;
  563.       }
  564.  
  565.       spmap.width = width;            /* in pixel */
  566.       spmap.height = height;          /* in pixel */
  567.  
  568.       if (scale_bmap(&spmap, &bitmap, &res, base_dpi, to_chip) == 2) {
  569.         /* kein CHIP-MEM verfuegbar */
  570.         to_chip = 0;
  571.         scale_bmap(&spmap, &bitmap, &res, base_dpi, to_chip);
  572.       }
  573.       spmap.loc.map = (unsigned long *)bitmap->Planes[0];
  574.  
  575.       if (draw_modus != DRAW_IN_MEM && draw_modus != DRAW_IN_MEM_B) {
  576.         pline("create file \"%s\"",full_name);
  577.         write_bmap(full_name, bitmap, ssum, spmap.width, spmap.height);
  578.       }
  579.     }
  580.     else {
  581.       pline("bitmap ERROR! (transferred no picture)");
  582.       message->ret = 5;        /* not used */
  583.     }
  584.       }
  585.     }
  586.   }
  587.  
  588.   return bitmap;
  589. }
  590.  
  591.  
  592. static int scale_bmap (struct special_map *map, struct BitMap **old_bmap,
  593.             struct parse_result *res, int base_dpi, short to_chip)
  594. {
  595.   USHORT new_width, new_height, map_width, map_height;
  596.   struct BitMap *new_bmap;
  597.   int i;
  598.  
  599.   /* to_chip: 0 = fast-mem, 1 = chip-mem        */
  600.   /* RETURN: 0 = ok, 1 = *no* mem, 2 = no chip-mem    */
  601.  
  602.   struct DateStamp Date1, Date2;
  603.   long diff;
  604.  
  605.   new_width  = (map->width * res->hres * 10 + 5) / (base_dpi * 10);
  606.   new_height = (map->height * res->vres * 10 + 5) / (base_dpi * 10);
  607.  
  608.   if (res->hsize != 0.0) {
  609.     /* width = hsize * hres */
  610.     new_width = (long)((res->hsize * (float)res->hres * 10.0 + 5.0) / 10.0);
  611.   }
  612.   if (res->vsize != 0.0) {
  613.     /* height = vsize * vres */
  614.     new_height = (long)((res->vsize * (float)res->vres * 10.0 + 5.0) / 10.0);
  615.   }
  616.  
  617.   if (ECS_chips) {    /* Die genaue Groesse kenn ich nicht (??) */
  618.     if ((new_width > (1<<15)-1) || (new_height > (1<<15)-1)) {
  619.       to_chip = FALSE;
  620.     }
  621.   }
  622.   else {
  623.     if ((new_width > 1023) || (new_height > 1023)) {
  624.       to_chip = FALSE;
  625.     }
  626.   }
  627.  
  628.   if (new_width != map->width || new_height != map->height) {
  629.  
  630.     if (map->where_is == LOC_BORDER || map->where_is == LOC_RECTANGLE) {
  631.       map->width  = new_width;
  632.       map->height = new_height;
  633.     }
  634.     else {
  635.       if (map->where_is == LOC_BITMAP || map->where_is == LOC_BITMAP_BORDER) {
  636.  
  637.     if ((new_bmap = malloc(sizeof(struct BitMap))) == NULL) {
  638.         pline("NOT ENOUGH MEMORY!!! (picture not resized)");
  639.         return 1;    /* *no* mem */
  640.     }
  641.     for (i=0; i<8; i++) {        /* important */
  642.         new_bmap->Planes[i] = NULL;
  643.     }
  644.  
  645.     /* Olsen: Initialisierung durch Systemroutine. */
  646.  
  647.     InitBitMap(new_bmap,1,new_width,new_height);
  648.     /* new_bmap->Flags       = (*old_bmap)->Flags; (???) */
  649.  
  650.     if (to_chip) {
  651.       new_bmap->Planes[0] = AllocMem(new_bmap->BytesPerRow*new_bmap->Rows,MEMF_CHIP|MEMF_CLEAR);
  652.     }
  653.     else {
  654.       new_bmap->Planes[0] = AllocMem(new_bmap->BytesPerRow*new_bmap->Rows,MEMF_PUBLIC|MEMF_CLEAR);
  655.     }
  656.     if (new_bmap->Planes[0] == NULL) {
  657.       free_bmap(&new_bmap);
  658.       pline("NOT ENOUGH MEMORY!!! (%s-mem)", (to_chip) ? "chip" : "fast");
  659.       if (to_chip) {
  660.         return 2;    /* no chip mem */
  661.       }
  662.       else {
  663.         return 1;    /* no fastmem */
  664.       }
  665.     }
  666.  
  667.         DateStamp(&Date1);
  668.  
  669.     map_width = map->width; map_height = map->height;
  670.  
  671.     if (res->mode == BandW) {
  672.       if (to_chip) {
  673.  
  674.         if (is_os2) {
  675.           struct BitScaleArgs bsa;
  676.           
  677.           bsa.bsa_SrcX        = 0;
  678.           bsa.bsa_SrcY        = 0;
  679.           bsa.bsa_SrcWidth    = map->width;
  680.           bsa.bsa_SrcHeight    = map->height;
  681.           bsa.bsa_XSrcFactor    = map->width;
  682.           bsa.bsa_YSrcFactor    = map->height;
  683.           bsa.bsa_DestX        = 0;
  684.           bsa.bsa_DestY        = 0;
  685.           /** bsa.bsa_DestWidth      = ; **/
  686.           /** bsa.bsa_DestHeight  = ; **/
  687.           bsa.bsa_XDestFactor    = new_width;
  688.           bsa.bsa_YDestFactor    = new_height;
  689.           bsa.bsa_SrcBitMap    = *old_bmap;
  690.           bsa.bsa_DestBitMap    = new_bmap;
  691.           bsa.bsa_Flags        = 0;
  692.           BitMapScale(&bsa);
  693.         }
  694.         else {
  695.  
  696.           /* Olsen:    Skalierung mit dem Blitter statt Zeile für
  697.            *        Zeile.
  698.            */
  699.  
  700.           if (!ResizeBitMap(*old_bmap,new_bmap,map_width,map_height,new_width,new_height)) {
  701.             FreeMem(new_bmap->Planes[0],new_bmap->BytesPerRow*new_bmap->Rows);
  702.             free_bmap(&new_bmap);
  703.             pline("NOT ENOUGH MEMORY!!! (chip-mem)");
  704.             return 2;
  705.           }
  706.         }
  707.       }
  708.       else {
  709.        extract_one((*old_bmap)->Planes[0],   new_bmap->Planes[0],
  710.                (*old_bmap)->BytesPerRow, new_bmap->BytesPerRow,
  711.                map_width, map_height,
  712.                new_width, new_height);
  713.       }
  714.     }
  715.     else {
  716.       dither(*old_bmap, map_width, new_bmap, new_width, res->mode == Ham);
  717.     }
  718.  
  719.       DateStamp(&Date2);
  720.       diff = (Date2.ds_Days - Date1.ds_Days) * (24 * 60);
  721.       diff = (diff + (Date2.ds_Minute - Date1.ds_Minute)) * 60 * TICKS_PER_SECOND;
  722.       diff += Date2.ds_Tick - Date1.ds_Tick;
  723.       pline("   Time: %7ld.%02ld Seconds", diff / TICKS_PER_SECOND,
  724.           ((diff % TICKS_PER_SECOND) * 100) / TICKS_PER_SECOND);
  725.  
  726.     map->width  = new_width;
  727.     map->height = new_height;
  728.  
  729.     free_bmap(old_bmap);
  730.  
  731.     *old_bmap = new_bmap;
  732.  
  733.       }
  734.     }
  735.   }
  736.   return 0;
  737. }
  738.  
  739.  
  740.  
  741.  
  742. void install_special_port(struct MsgPort **special_port)
  743. {
  744.   Forbid();
  745.   *special_port = FindPort(SPECIAL_PORT);
  746.   if (*special_port != NULL) {
  747.     Permit();
  748.     Fatal(NOT_FIRST);
  749.   }
  750.   *special_port = (struct MsgPort *)CreatePort(SPECIAL_PORT,0L);
  751.   Permit();
  752.  
  753.   if (*special_port == NULL) {
  754.     Fatal(NO_PORT);
  755.   }
  756. }
  757.  
  758.  
  759.  
  760. long work_with_special(int draw_modus, int base_dpi)
  761. {
  762.   struct special_msg *message;
  763.   long ret = 0;
  764.  
  765.   while ((message = (struct special_msg *)GetMsg(special_port)) != NULL) {
  766.  
  767.     if (message != NULL) {
  768.       switch (message->action) {
  769.  
  770.         case AC_SEND_SPECIAL:
  771.           bmap = work_with_message(message, draw_modus, base_dpi);
  772.           message->action = AC_REPLY_SPECIAL;
  773.           ReplyMsg(&(message->msg));
  774.  
  775.           WaitPort(special_port);
  776.  
  777.           message = (struct special_msg *)GetMsg(special_port);
  778.           if (message == NULL) {
  779.         Fatal(NO_MESSAGE);
  780.           }
  781.           if (message->action != AC_OK_BITMAP) {
  782.         pline("*** I have expected AC_REPLY_SPECIAL!!");
  783.         pline("    I found '%d' (see special.h)!",message->action);
  784.           }
  785.           message->action = AC_REPLY_BITMAP;
  786.           message->ret = 0;
  787.           ReplyMsg(&(message->msg));
  788.  
  789.           if (ifffile != NULL) {
  790.         CloseIFF(ifffile);
  791.         ifffile = NULL;
  792.           }
  793.           free_bmap(&bmap); /* bmap = NULL; macht nun schon free_bmap() */
  794.           break;
  795.  
  796.         case AC_SEND_TPIC:
  797.            /* pline("receive TPIC command %s",TPICstr[message->tpic->tpic_com]); */
  798.            work_with_tpic(message->tpic, message->dmap, message->hresolution, message->vresolution);
  799.            message->action = AC_REPLY_TPIC;
  800.            message->ret = 0;
  801.            ReplyMsg(&(message->msg));
  802.           break;
  803.  
  804.         default:
  805.           pline("*** Unknown action!?");
  806.       pline("    Maybe you need a newer SpecialHost version!");
  807.           message->action = AC_REPLY_UNKNOWN;
  808.           message->ret = 0;
  809.           ReplyMsg(&(message->msg));
  810.       break;
  811.       }
  812.     }
  813.   }
  814.  
  815.   return ret;
  816. }
  817.  
  818.